package org.jeecg.config.interceptor;

import cn.com.hhrcw.constant.CommonConstant;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Charsets;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

/**
 * 防重复提交拦截器
 *
 * @author: taoyan
 * @date: 2020年03月20日
 */
@Slf4j
@Component
public class SubmitInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod method = (HandlerMethod) handler;
        String mediaType = request.getHeader(HttpHeaders.CONTENT_TYPE);
        if(method.hasMethodAnnotation(PostMapping.class) && mediaType.startsWith(MediaType.APPLICATION_JSON_VALUE)){
            String token = ServletUtil.getHeader(request, CommonConstant.TOKEN, Charsets.UTF_8);

            byte[] bytes = IoUtil.readBytes(request.getInputStream());
            if(ArrayUtil.isEmpty(bytes)){
                return true;
            }
            TreeMap map = JSON.parseObject(new String(bytes), TreeMap.class);
            long time = DateUtil.date().getTime() / 1000;
            map.put(CommonConstant.TOKEN, token);
            String str = URLUtil.buildQuery(map,Charsets.UTF_8);
            if(!redisTemplate.hasKey(SecureUtil.md5(str))) {
                redisTemplate.opsForValue().set(SecureUtil.md5(str), time,30, TimeUnit.SECONDS);
            }else{
                long history = Convert.toLong(redisTemplate.opsForValue().get(SecureUtil.md5(str)));
                int sec = 30;
                if ((time - history) < sec) {
                    ServletUtil.write(response, JSON.toJSONString(Result.error("请不要重复提交")), MediaType.APPLICATION_JSON_UTF8_VALUE);
                    return false;
                }
            }
        }
        return true;
    }
}
